package display;

import image.Image;
import image.ImageCache;

import java.awt.Canvas;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.sampled.Clip;

import sun.management.snmp.jvmmib.JvmCompilationMBean;

import entity.misc.Entrance;
import entity.misc.Exit;
import entity.terrain.Terrain;

import level.*;

public class Game extends Canvas implements MouseListener, ActionListener{
	

    JLabel out;
    JLabel in;
    JLabel percentage;
	
	private int mouseXco;
	private int mouseYco;
	
	private JButton basherButton;
	private JButton blockerButton;
	private JButton builderButton;
	private JButton climberButton;
	private JButton diggerButton;
	private JButton exploderButton;
	private JButton floaterButton;
	private JButton minerButton;
	private JButton nukeButton;
	private JButton pawsButton;
	
	private int basher;
	private int blocker;
	private int bomber;
	private int bridger;
	private int climber;
	private int digger;
	private int floater;
	private int miner;
	
	JPanel menu;
	JPanel panel;
	JPanel bar;
	JFrame frame;
	
	private Border selected = new LineBorder(Color.green, 1);
	private Border unselected = new LineBorder(Color.white, 1);
    
	
	public static final int WIDTH = 322;

	public static final int HEIGHT = 235;

	public BufferStrategy buffStrat;

	/* Environment variables */
	Level level;
	Manager lemmings;
	Terrain terrain;
	Entrance entrance;
	Exit exit;
	Level[] levels;

	public Game() {
		frame = new JFrame("Lemmings");
		frame.setBackground(Color.black);
		frame.setBounds(0, 0, WIDTH, HEIGHT);
		setBounds(0, 0, WIDTH, HEIGHT);
		
		panel = (JPanel)frame.getContentPane();
		panel.setLayout(new BorderLayout(1,1));
		panel.setBackground(Color.black);
		//frame.getContentPane().add(panel);
		//frame.setContentPane(panel);
		
		
		//panel.setPreferredSize(new Dimension(200, 200));
		panel.add(BorderLayout.CENTER, this);
		
		// hack of a way to add butttons, gotta update but buttons will work!!!
		
		
		ImageIcon basherIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/basher/basher_1.gif")).getBufferedImage());
		ImageIcon blockerIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/blocker/blocker_1.gif")).getBufferedImage());
		ImageIcon builderIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/builder/builder_1.gif")).getBufferedImage());
		ImageIcon climberIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/climber/climber_1.gif")).getBufferedImage());
		ImageIcon diggerIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/digger/digger_1.gif")).getBufferedImage());
		ImageIcon floaterIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/floater/floater1r.gif")).getBufferedImage());
		ImageIcon minerIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/miner/miner_1.gif")).getBufferedImage());
		ImageIcon exploderIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/lemming/exploder/exploder_1.gif")).getBufferedImage());
		ImageIcon pawsIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/Buttons/PawsButton.gif")).getBufferedImage());
		ImageIcon nukeIcon = new ImageIcon((ImageCache.getCache().getSprite("resource/graphics/Buttons/NukeButton.gif")).getBufferedImage());
		
		bar = new JPanel();
		bar.setLayout(new BorderLayout());
		
		JPanel info = new JPanel();
		info.setLayout(new GridLayout(0,3));
		
		/***************************************/
		info.setBackground(Color.BLACK);
		
		
		out = new JLabel("out: ");
		in = new JLabel("in: ");
		percentage = new JLabel("%: ");
		
		out.setForeground(Color.GREEN);
		in.setForeground(Color.GREEN);
		percentage.setForeground(Color.GREEN);
		
		info.add(out);
		info.add(in);
		info.add(percentage);
		/***************************************/
		
		
		
		menu = new JPanel();
		menu.setLayout(new GridLayout(1,8));
		
		basherButton = new JButton("0", basherIcon);
		basherButton.setBackground(Color.GRAY);
		basherButton.setVerticalTextPosition(AbstractButton.NORTH);
        basherButton.setHorizontalTextPosition(AbstractButton.CENTER);
		basherButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, basherButton);
		
		blockerButton = new JButton("0", blockerIcon);
		blockerButton.setBackground(Color.GRAY);
		blockerButton.setVerticalTextPosition(AbstractButton.NORTH);
		blockerButton.setHorizontalTextPosition(AbstractButton.CENTER);
		blockerButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, blockerButton);
		

		builderButton = new JButton("0", builderIcon);
		builderButton.setBackground(Color.GRAY);
		builderButton.setVerticalTextPosition(AbstractButton.NORTH);
		builderButton.setHorizontalTextPosition(AbstractButton.CENTER);
		builderButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, builderButton);
		
		climberButton = new JButton("0", climberIcon);
		climberButton.setBackground(Color.GRAY);
		climberButton.setVerticalTextPosition(AbstractButton.NORTH);
		climberButton.setHorizontalTextPosition(AbstractButton.CENTER);
		climberButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, climberButton);
		
		diggerButton = new JButton("0", diggerIcon);
		diggerButton.setBackground(Color.GRAY);
		diggerButton.setVerticalTextPosition(AbstractButton.NORTH);
		diggerButton.setHorizontalTextPosition(AbstractButton.CENTER);
		diggerButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, diggerButton);
		
		exploderButton = new JButton("0", exploderIcon);
		exploderButton.setBackground(Color.GRAY);
		exploderButton.setVerticalTextPosition(AbstractButton.NORTH);
		exploderButton.setHorizontalTextPosition(AbstractButton.CENTER);
		exploderButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, exploderButton);
		
		floaterButton = new JButton("0", floaterIcon);
		floaterButton.setBackground(Color.GRAY);
		floaterButton.setVerticalTextPosition(AbstractButton.NORTH);
		floaterButton.setHorizontalTextPosition(AbstractButton.CENTER);
		floaterButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, floaterButton);
		
		minerButton = new JButton("0", minerIcon);
		minerButton.setBackground(Color.GRAY);
		minerButton.setVerticalTextPosition(AbstractButton.NORTH);
		minerButton.setHorizontalTextPosition(AbstractButton.CENTER);
		minerButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, minerButton);
		
		pawsButton = new JButton(pawsIcon);
		pawsButton.setBackground(Color.GRAY);
		pawsButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, pawsButton);
		
		nukeButton = new JButton(nukeIcon);
		nukeButton.setBackground(Color.GRAY);
		nukeButton.addActionListener(this);
		panel.add(BorderLayout.SOUTH, nukeButton);
		
		// just to ensure all borders are cleared
		clearButtonBorder();
		
		menu.add(basherButton);
		menu.add(blockerButton);
		menu.add(builderButton);
		menu.add(climberButton);
		menu.add(diggerButton);
		menu.add(exploderButton);
		menu.add(floaterButton);
		menu.add(minerButton);
		menu.add(pawsButton);
		menu.add(nukeButton);
		
		bar.add(BorderLayout.NORTH, menu);
		bar.add(BorderLayout.SOUTH, info);
		panel.add(BorderLayout.SOUTH, bar);
		//----------------------------------
		
		frame.setBounds(50, 50, WIDTH, HEIGHT);
		frame.setVisible(true);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		// Register for mouse events on frame.
		frame.addMouseListener(this);
        addMouseListener(this);
        createBufferStrategy(2);
        buffStrat = getBufferStrategy();
        
    	//this.run();

	} //end of construtor
	
	/** Returns an ImageIcon, or null if the path was invalid. */
	protected static ImageIcon createImageIcon(String path,
	                                           String description) {
	    java.net.URL imgURL = Game.class.getResource(path);
	    if (imgURL != null) {
	        return new ImageIcon(imgURL, description);
	    } else {
	        System.err.println("Couldn't find file: " + path);
	        return null;
	    }
	}

	// Draw the splash screen
	public void SplashScreen(){
		Graphics g = buffStrat.getDrawGraphics();
		g.setColor(Color.black);
		g.fillRect(0,0,getWidth(),getHeight());
		
		Font f = new Font("Courier", Font.BOLD,  20);
		g.setFont(f);
		g.setColor(Color.white);
		g.drawString("Welcome to", 95, 30);
		
		// Draw the logo
		BufferedImage img = (ImageCache.getCache().getSprite("resource/graphics/menu/logo.gif")).getBufferedImage();
		g.drawImage(img, 60, 30, null);
		
		buffStrat.show();
		g.dispose();
	}
	
//	 Draw the splash screen
	public void levelPreview(int num, int save){
		Graphics g = buffStrat.getDrawGraphics();
		g.setColor(Color.black);
		g.fillRect(0,0,getWidth(),getHeight());
		
		Font f = new Font("Courier", Font.BOLD,  20);
		g.setFont(f);
		g.setColor(Color.white);
		g.drawString("Level 1", 95, 30);
		
		f = new Font("Courier", Font.BOLD,  15);
		
		g.setFont(f);
		g.setColor(Color.white);
		g.drawString("Num of Lemmings: " + num, 105, 50);
		
		g.setFont(f);
		g.setColor(Color.white);
		g.drawString("Num to Save: " + save, 105, 70);
		
		g.setFont(f);
		g.setColor(Color.white);
		g.drawString("Percentage: " + save/num*100, 105, 90);
		
		buffStrat.show();
		g.dispose();
	}
	
	
	public void init() {
		terrain = new Terrain("resource/graphics/levels/One/level1.gif",
				1, false, false);
		entrance = new Entrance( 
				"resource/graphics/levels/One/entrance_1.gif",76,30);
		exit = new Exit(
				"resource/graphics/levels/One/exit_1.gif",235, 105);
		level = new Level(93, 35, 245, 120, 200, 1, terrain, entrance, exit);
		lemmings = new Manager(10, level);
		setButtons(0, 0, 0, 0, 0, 10, 0, 10);
	}
	
	public void level1(){
		terrain = new Terrain("resource/graphics/levels/One/level1.gif",
				1, false, false);
		entrance = new Entrance( 
				"resource/graphics/levels/One/entrance_1.gif",12,38);
		exit = new Exit(
				"resource/graphics/levels/One/exit_1.gif",149, 102);
		level = new Level(34, 40, 162, 119, 200, 1, terrain, entrance, exit);
		lemmings = new Manager(10, level);
		setButtons(0,0,0,0,0,10,0,0);
	}
	
	public void level2(){
		terrain = new Terrain("resource/graphics/levels/Two/Level_2.gif",
				1, false, false);
		entrance = new Entrance( 
				"resource/graphics/levels/One/entrance_1.gif",20,9);
		exit = new Exit(
				"resource/graphics/levels/Two/Exit_1.gif",254, 123);
		level = new Level(39, 16, 270, 137, 200, 1, terrain, entrance, exit);
		lemmings = new Manager(10, level);
		setButtons(0,0,0,0,0,0,10,0);
	}
	
	public void level3(){
		terrain = new Terrain("resource/graphics/levels/Three/Level_3.gif",
				1, false, false);
		entrance = new Entrance( 
				"resource/graphics/levels/One/entrance_1.gif",120,2);
		exit = new Exit(
				"resource/graphics/levels/One/exit_1.gif",189, 126);
		level = new Level(142, 9, 201, 143, 200, 1, terrain, entrance, exit);
		lemmings = new Manager(10, level);
		setButtons(0,10,0,0,0,0,0,0);
	}
	
	public void level4(){
		terrain = new Terrain("resource/graphics/levels/Four/level4.gif",
				1, false, false);
		entrance = new Entrance( 
				"resource/graphics/levels/One/entrance_1.gif",95,10);
		exit = new Exit(
				"resource/graphics/levels/Four/exit_1.gif",247, 24);
		level = new Level(112, 28, 260, 30, 200, 1, terrain, entrance, exit);
		lemmings = new Manager(1, level);
		setButtons(0,0,0,10,10,10,10,10);
		
	}

	public void logic() {
		lemmings.play();
		out.setText("out: " + lemmings.getAlive());
		in.setText("in: " + lemmings.getSaved());
		percentage.setText("%: " + lemmings.percentage());
		
		if (lemmings.eventUsed()){
			if (basherButton.getBorder() == selected){
				basher--;
				basherButton.setText(""+basher);
				if(basher==0){
					basherButton.setEnabled(false);
				}
			} else if(builderButton.getBorder() == selected){
				bridger--;
				builderButton.setText(""+bridger);
				if(bridger==0){
					builderButton.setEnabled(false);
				}
				
			} else if(blockerButton.getBorder() == selected){
				blocker--;
				blockerButton.setText(""+blocker);
				if(blocker==0){
					blockerButton.setEnabled(false);
				}
			} else if(climberButton.getBorder() == selected){
				climber--;
				climberButton.setText(""+climber);
				if(climber==0){
					climberButton.setEnabled(false);
				}
			} else if(exploderButton.getBorder() == selected){
				bomber--;
				exploderButton.setText(""+bomber);
				if(bomber==0){
					exploderButton.setEnabled(false);
				}
			} else if(minerButton.getBorder() == selected){
				miner--;
				minerButton.setText(""+miner);
				if(miner==0){
					minerButton.setEnabled(false);
				}
			} else if(diggerButton.getBorder() == selected){
				digger--;
				diggerButton.setText(""+digger);
				if(digger==0){
					diggerButton.setEnabled(false);
				}
				
			} else if(floaterButton.getBorder() == selected){
				floater--;
				floaterButton.setText(""+floater);
				if(floater==0){
					floaterButton.setEnabled(false);
				}
			} 
		}
		lemmings.setUnUsed();
		
	}
	
	public void paintWorld(){
		Graphics g = buffStrat.getDrawGraphics();
		g.setColor(Color.black);
		g.fillRect(0,0,getWidth(),getHeight());
		try {
			lemmings.draw(g);
		} catch (NullPointerException e){
			
		}
		buffStrat.show();
		g.dispose();
	}
	
	/*public void paint(Graphics g){
		g = buffStrat.getDrawGraphics();
		g.setColor(Color.black);
		g.fillRect(0,0,getWidth(),getHeight());
		try {
			lemmings.draw(g);
		} catch (NullPointerException e){
			
		}
		buffStrat.show();
	}*/

	public void run() {
		int i = 0;
		while (i++ < 1000){
			SplashScreen();
		}
		
		
		i = 0;
		while (i++ < 1000){
			levelPreview(10, 10);
		}
		
		init();
		while (!lemmings.gameOver()) {
			logic();
			paintWorld();
			try {
				Thread.sleep(75);
			} catch (InterruptedException e) {
			}
		}
		
		i = 0;
		while (i++ < 1000){
			levelPreview(10, 3);
		}
		
		level2();
		while (!lemmings.gameOver()) {
			logic();
			paintWorld();
			try {
				Thread.sleep(75);
			} catch (InterruptedException e) {
			}
		}
		
		i = 0;
		while (i++ < 1000){
			levelPreview(10, 5);
		}
		
		level3();
		while (!lemmings.gameOver()) {
			logic();
			paintWorld();
			try {
				Thread.sleep(75);
			} catch (InterruptedException e) {
			}
		}
		
		i = 0;
		while (i++ < 1000){
			levelPreview(10, 10);
		}
		
		level4();
		while (!lemmings.gameOver()) {
			logic();
			paintWorld();
			try {
				Thread.sleep(75);
			} catch (InterruptedException e) {
			}
		}
		
		//System.out.println("GAMEOVER!!!");
		//repaint();
	}
	
	private void setButtons(int basher, int blocker, int bomber, int bridger, int climber, int digger, int floater, int miner){
		
		this.basher = basher;
		this.blocker = blocker;
		this.bridger = bridger;
		this.climber = climber;
		this.digger = digger;
		this.floater = floater;
		this.miner = miner;
		
		if(basher == 0){
			basherButton.setEnabled(false);
		}else{
			basherButton.setText(""+basher);
			basherButton.setEnabled(true);
		}
		
		if(blocker == 0){
			blockerButton.setEnabled(false);
		}else{
			blockerButton.setText(""+blocker);
			blockerButton.setEnabled(true);
		}
		
		if(bomber == 0){
			exploderButton.setEnabled(false);
		}else{
			exploderButton.setText(""+bomber);
			exploderButton.setEnabled(true);
		}
		if(bridger == 0){
			builderButton.setEnabled(false);
		}else{
			builderButton.setText(""+bridger);
			basherButton.setEnabled(true);
		}
		if(climber == 0){
			climberButton.setEnabled(false);
		}else{
			climberButton.setText(""+climber);
			climberButton.setEnabled(true);
		}
		if(digger == 0){
			diggerButton.setEnabled(false);
		}else{
			diggerButton.setText(""+digger);
			diggerButton.setEnabled(true);
		}
		if(floater == 0){
			floaterButton.setEnabled(false);
		}else{
			floaterButton.setText(""+floater);
			floaterButton.setEnabled(true);
		}
		if(miner == 0){
			minerButton.setEnabled(false);
		}else{
			minerButton.setText(""+miner);
			minerButton.setEnabled(true);
		}
		
	}

	private void clearButtonBorder(){
		basherButton.setBorder(unselected);
		blockerButton.setBorder(unselected);
		builderButton.setBorder(unselected);
		climberButton.setBorder(unselected);
		diggerButton.setBorder(unselected);
		exploderButton.setBorder(unselected);
		floaterButton.setBorder(unselected);
		minerButton.setBorder(unselected);
		nukeButton.setBorder(unselected);
		pawsButton.setBorder(unselected);
	}
	
	public static void main(String[] args) {
		Game game = new Game();
		game.run();
	}

	public void mouseDragged(MouseEvent e) {
		// do nothing
	}

    public void mousePressed(MouseEvent e) {
     
     }

     public void mouseReleased(MouseEvent e) {
      
     }

     public void mouseEntered(MouseEvent e) {
      
     }

     public void mouseExited(MouseEvent e) {
      
     }

     public void mouseClicked(MouseEvent e) {
    	 mouseXco = e.getX();
    	 mouseYco = e.getY();
    	 System.out.println("x co: "+mouseXco+" y co: "+mouseYco);
    	 lemmings.setMouseCoordinates(mouseXco, mouseYco);
     }

	public void actionPerformed(ActionEvent e) {
		clearButtonBorder();
		
		if(e.getSource()== basherButton){
			System.out.println("Basher Selected");
			lemmings.mouseEvents("Basher");
			basherButton.setBorder(selected);
			
			
		}
		else if(e.getSource()== blockerButton){
			System.out.println("Blocker Selected");
			lemmings.mouseEvents("Blocker");
			blockerButton.setBorder(selected);

		}
		else if(e.getSource()== builderButton){
			System.out.println("Builder Selected");
			lemmings.mouseEvents("Builder");
			builderButton.setBorder(selected);

		}
		else if(e.getSource()== climberButton){
			System.out.println("Climber Selected");
			lemmings.mouseEvents("Climber");
			climberButton.setBorder(selected);

		}
		else if(e.getSource()== diggerButton){
			System.out.println("Digger Selected");
			lemmings.mouseEvents("Digger");
			diggerButton.setBorder(selected);

		}
		else if(e.getSource()== exploderButton){
			System.out.println("Exploder Selected");
			lemmings.mouseEvents("Bomber");
			exploderButton.setBorder(selected);

		}
		else if(e.getSource()== floaterButton){
			System.out.println("Floater Selected");
			lemmings.mouseEvents("Floater");
			floaterButton.setBorder(selected);

		}
		else if(e.getSource()== minerButton){
			System.out.println("Miner Selected");
			lemmings.mouseEvents("Miner");
			minerButton.setBorder(selected);

		}
		else if(e.getSource()== nukeButton){
			System.out.println("Nuke Selected");
			lemmings.mouseEvents("Nuke");
			nukeButton.setBorder(selected);
		}
		else if(e.getSource()== pawsButton){
			System.out.println("Paws Selected");
			lemmings.mouseEvents("Paws");
			pawsButton.setBorder(selected);
		}
	}

	public void meta(MetaMessage arg0) {
		
	}

	public int getBasher() {
		return basher;
	}

	public void setBasher(int basher) {
		this.basher = basher;
	}

	public int getBlocker() {
		return blocker;
	}

	public void setBlocker(int blocker) {
		this.blocker = blocker;
	}

	public int getBomber() {
		return bomber;
	}

	public void setBomber(int bomber) {
		this.bomber = bomber;
	}

	public int getBridger() {
		return bridger;
	}

	public void setBridger(int bridger) {
		this.bridger = bridger;
	}

	public int getClimber() {
		return climber;
	}

	public void setClimber(int climber) {
		this.climber = climber;
	}

	public int getDigger() {
		return digger;
	}

	public void setDigger(int digger) {
		this.digger = digger;
	}

	public int getFloater() {
		return floater;
	}

	public void setFloater(int floater) {
		this.floater = floater;
	}

	public int getMiner() {
		return miner;
	}

	public void setMiner(int miner) {
		this.miner = miner;
	}

  


}